home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power Programmierung
/
Power-Programmierung (Tewi)(1994).iso
/
magazine
/
msysjour
/
vol06
/
03
/
winedd
/
logger.c
< prev
next >
Wrap
Text File
|
1991-05-01
|
15KB
|
466 lines
/* ----------------------------- LOGGER.C ----------------------------------
Embedded Device Driver Application.
Application module.
Spark Software Inc. 1991.
------------------------------------------------------------------------- */
/* The following is an intentionally empty definition; this is used to tell */
/* the compiler that we wish to have the global variables in "globals.h" */
/* declared in this source module and only defined in all others. */
#define PUBLIC
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include "device.h"
#include "logmsg.h"
#include "defs.h"
/* Macro definitions. */
#define ShowRegisters( ) \
sprintf( szString , \
"%04X %04X %04X %04X " \
"%04X:%04X %04X:%04X " \
"%04X:%04X %04X %04X" , \
Registers.ax , Registers.bx , Registers.cx , Registers.dx , \
Registers.cs , Registers.ip , Registers.ds , Registers.si , \
Registers.es , Registers.di , Registers.bp , Registers.sp );\
TextOut( hDC , 0 , nY , szString , strlen( szString ) );
/* Public function prototypes. */
PUBLIC int PASCAL WinMain( HANDLE , HANDLE , LPSTR , int );
PUBLIC LONG FAR PASCAL AppWndProc( HWND , WORD , WORD , LONG );
/* Private function prototypes. */
PRIVATE VOID NEAR PASCAL GetNewData( HWND , WORD );
PRIVATE BOOL NEAR PASCAL Init( HANDLE );
PRIVATE LPSTR NEAR PASCAL FormatDevErrorMsg( WORD , WORD );
PRIVATE LONG NEAR PASCAL DoClose( HWND );
PRIVATE LONG NEAR PASCAL DoCreate( HWND );
PRIVATE LONG NEAR PASCAL DoDestroy( HWND );
PRIVATE LONG NEAR PASCAL DoPaint( HWND );
PRIVATE LONG NEAR PASCAL DoSize( HWND , WORD );
/* Private data object declarations. */
PRIVATE BOOL bDisplayed; /* Displayed >= 1 set of registers? */
PRIVATE BOOL bOpened; /* Was the pseudodevice opened? */
PRIVATE BOOL bError; /* Did we get a read error? */
PRIVATE BYTE szAppName[ ] = APP_NAME; /* Application name. */
PRIVATE BYTE szClass[ ] = APP_CLASS; /* Window class name. */
PRIVATE BYTE szColumnHeadings[ ] = COLUMN_HEADINGS; /* Obv. */
PRIVATE BYTE szString[ 81 ]; /* Generic text buffer. */
PRIVATE WORD wCharWidth , wCharHeight; /* Font information. */
PRIVATE WORD wLoggerDefunctMsg; /* For message sent when we stop. */
PRIVATE HANDLE hInst , hPrevInst; /* Handles to program instances. */
PRIVATE HWND hWndMaster; /* Handle of our master window. */
PRIVATE REGISTERS Registers; /* Buffer for machine registers. */
PUBLIC int PASCAL WinMain( hInstance , hPrevInstance , lpszCmdLine , nCmdShow )
HANDLE hInstance , hPrevInstance;
LPSTR lpszCmdLine;
int nCmdShow;
{
WORD wItems , wExecReturn;
MSG Msg;
/* Call initialization procedure if this is the first instance. */
if( !hPrevInstance && !Init( hInstance ) )
return 0;
if( hPrevInstance )
{
/* See if the top-level window of this app still exists. */
GetInstanceData( hPrevInstance , (PSTR)&hWndMaster , sizeof hWndMaster );
if( IsWindow( hWndMaster ) )
{
/* We won't allow more than one invocation of this program. */
sprintf( szString , "%s already active." , APP_NAME );
MessageBox( GetFocus( ) , (LPSTR)szString , (LPSTR)szAppName , MB_OK | MB_ICONHAND );
return 0;
}
}
/* Create our top-level (i.e., master) window. */
hWndMaster = CreateWindow(
(LPSTR)szClass ,
(LPSTR)szAppName ,
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN ,
CW_USEDEFAULT ,
0 ,
CW_USEDEFAULT ,
0 ,
(HWND)NULL ,
(HMENU)NULL ,
hInstance ,
(LPSTR)NULL
);
hInst = hInstance;
hPrevInst = hPrevInstance;
/* Start up the feeder (device simulator). */
if( ( wExecReturn = WinExec( FEEDER_APP_NAME , SW_SHOWMINIMIZED ) ) <= 32 )
{
sprintf( szString , "Cannot execute %s; error %u" , FEEDER_APP_NAME , wExecReturn );
MessageBox( GetFocus( ) , (LPSTR)szString , (LPSTR)szAppName , MB_OK | MB_ICONHAND );
}
/* Show the window and send keyboard input to it. */
ShowWindow( hWndMaster , nCmdShow );
SetFocus( hWndMaster );
/* Process messages from our queue. */
while( TRUE )
{
if( PeekMessage( (LPMSG)&Msg , NULL , 0 , 0 , PM_REMOVE ) )
{
if( Msg.message == WM_QUIT )
{
return (int)Msg.wParam;
}
TranslateMessage( (LPMSG)&Msg );
DispatchMessage( (LPMSG)&Msg );
}
/* If there are one or more unread items in the interrupt buffer... */
/* NOTE: working in this part of the message loop allows */
/* us to process input when we have 0 or more messages. */
if( bOpened && !bError && ( wItems = GetNumUnreadItems( hWndMaster ) ) )
{
/* Process the unread data NOW. */
GetNewData( hWndMaster , wItems );
}
}
}/* WinMain( ) */
/* Procedure called when the application is loaded for the first time */
PRIVATE BOOL NEAR PASCAL Init( hInstance )
HANDLE hInstance;
{
WNDCLASS Class;
/* Register the window class. */
Class.hCursor = LoadCursor( NULL, IDC_ARROW );
Class.hIcon = LoadIcon( hInstance , MAKEINTRESOURCE( APPICON ) );
Class.lpszMenuName = (LPSTR)NULL;
Class.lpszClassName = (LPSTR)szClass;
Class.hbrBackground = GetStockObject( WHITE_BRUSH );
Class.hInstance = hInstance;
Class.style = CS_HREDRAW | CS_VREDRAW;
Class.lpfnWndProc = AppWndProc;
Class.cbClsExtra = 0;
Class.cbWndExtra = 0;
if( !RegisterClass( (LPWNDCLASS)&Class ) )
/* Initialization failed. */
return FALSE;
return TRUE;
}/* Init( ) */
PUBLIC LONG FAR PASCAL AppWndProc( hWnd , wMessage , wParam , lParam )
HWND hWnd;
WORD wMessage;
WORD wParam;
LONG lParam;
{
switch( wMessage )
{
case WM_CREATE:
return DoCreate( hWnd );
case WM_CLOSE:
return DoClose( hWnd );
case WM_DESTROY:
return DoDestroy( hWnd );
case WM_SIZE:
return DoSize( hWnd , wParam );
case WM_PAINT:
return DoPaint( hWnd );
}
return DefWindowProc( hWnd , wMessage , wParam , lParam );
}/* AppWndProc( ) */
/* Create and/or access all resources to be used in this application. */
PRIVATE LONG NEAR PASCAL DoCreate( hWnd )
HWND hWnd;
{
HFONT hOldFont;
HDC hDC;
TEXTMETRIC tmInfo;
/* Get some info. about our font and screen. */
hDC = GetDC( hWnd );
hOldFont = SelectObject( hDC , GetStockObject( SYSTEM_FIXED_FONT ) );
GetTextMetrics( hDC , (LPTEXTMETRIC)&tmInfo );
SelectObject( hDC , hOldFont );
ReleaseDC( hWnd , hDC );
wCharWidth = tmInfo.tmAveCharWidth;
wCharHeight = tmInfo.tmHeight + tmInfo.tmExternalLeading;
/* Open the device. */
bOpened = DevOpen( hWnd );
/* Register a message index to be sent when we are about to stop. */
wLoggerDefunctMsg = RegisterWindowMessage( LOGGER_DEFUNCT_MSG );
return (LONG)1;
return (LONG)1;
}/* DoCreate( ) */
PRIVATE LONG NEAR PASCAL DoClose( hWnd )
HWND hWnd;
{
/* LOGGER is terminating; tell FEEDER. */
SendMessage( (HWND)-1 , wLoggerDefunctMsg , 0 , (LONG)0 );
DestroyWindow( hWnd );
return (LONG)1;
}/* DoClose( ) */
/* Destroy and/or relinquish all resources used in this application. */
PRIVATE LONG NEAR PASCAL DoDestroy( hWnd )
HWND hWnd;
{
/* Close the pseudodevice. */
DevClose( hWnd );
bOpened = FALSE;
/* Finish up. */
PostQuitMessage( 0 );
return (LONG)1;
}/* DoDestroy( ) */
PRIVATE LONG NEAR PASCAL DoSize( hWnd , wParam )
HWND hWnd;
WORD wParam;
{
HDC hDC;
HFONT hOldFont;
RECT rInfo;
if( wParam == SIZENORMAL )
{
/* Size the window according to its text. */
hDC = GetDC( hWnd );
hOldFont = SelectObject( hDC , GetStockObject( SYSTEM_FIXED_FONT ) );
GetClientRect( hWnd , (LPRECT)&rInfo );
rInfo.bottom = rInfo.top + wCharHeight * 2;
rInfo.right = rInfo.left + wCharWidth * 72;
AdjustWindowRect( (LPRECT)&rInfo , GetWindowLong( hWnd , GWL_STYLE ) , FALSE );
SetWindowPos( hWnd , (HWND)NULL , 0 , 0 , rInfo.right - rInfo.left , rInfo.bottom - rInfo.top , SWP_NOMOVE | SWP_NOZORDER );
SelectObject( hDC , hOldFont );
ReleaseDC( hWnd , hDC );
}
return (LONG)1;
}/* DoSize( ) */
PRIVATE LONG NEAR PASCAL DoPaint( hWnd )
HWND hWnd;
{
register int nY;
HFONT hOldFont;
HDC hDC;
PAINTSTRUCT psInfo;
/* Resize the window. */
/* Select a monospace font. */
hDC = BeginPaint( hWnd , (LPPAINTSTRUCT)&psInfo );
hOldFont = SelectObject( hDC , GetStockObject( SYSTEM_FIXED_FONT ) );
/* Was the window erased? */
if( !psInfo.fErase )
{
/* Window was not erased. Since we're only showing the */
/* last item gotten from the driver (and several items */
/* may have been displayed previously), erase the window. */
SendMessage( hWnd , WM_ERASEBKGND , (WORD)hDC , (LONG)0 );
}
/* Start at the first line of text in the window. */
nY = 0;
TextOut( hDC , 0 , nY , szColumnHeadings , strlen( szColumnHeadings ) );
/* If we displayed at least one set of registers... */
if( bDisplayed )
{
/* ...Display the register contents for the last interrupt. */
nY += wCharHeight;
ShowRegisters( );
}
SelectObject( hDC , hOldFont );
EndPaint( hWnd , (LPPAINTSTRUCT)&psInfo );
return (LONG)1;
}/* DoPaint( ) */
PRIVATE VOID NEAR PASCAL GetNewData( hWnd , wItems )
HWND hWnd;
WORD wItems;
{
WORD wDevError , wNumErrors;
register int nY;
HFONT hOldFont;
HDC hDC;
hDC = GetDC( hWnd );
hOldFont = SelectObject( hDC , GetStockObject( SYSTEM_FIXED_FONT ) );
/* Read the data from the pseudodevice's buffer. */
for(
nY = 0;
wItems && DevRead( hWnd , (LPREGISTERS)&Registers , 1 );
nY += wCharHeight , wItems--
)
{
if( !nY )
{
/* Erase the window upon reading the first item. */
SendMessage( hWnd , WM_ERASEBKGND , (WORD)hDC , (LONG)0 );
/* Display the column headings. */
TextOut( hDC , 0 , nY , szColumnHeadings , strlen( szColumnHeadings ) );
nY += wCharHeight;
}
/* Check for a device error on this read. */
if( ( wNumErrors = GetDevError( hWnd , (LPWORD)&wDevError , TRUE ) ) )
{
bError = TRUE;
Registers.ax = Registers.bx = Registers.cx = Registers.dx =
Registers.cs = Registers.ds = Registers.es = Registers.si =
Registers.di = Registers.bp = Registers.sp = Registers.ip =
Registers.flags = 0;
MessageBox( GetFocus( ) , FormatDevErrorMsg( wDevError , wNumErrors ) , (LPSTR)szAppName , MB_OK | MB_ICONHAND );
}
else
{
/* Display the register contents for all interrupts */
/* that occurred since the last read. */
ShowRegisters( );
}
}
/* Check for a device error on the last read if DevRead( ) returned 0. */
if( ( wNumErrors = GetDevError( hWnd , (LPWORD)&wDevError , TRUE ) ) )
{
bError = TRUE;
MessageBox( GetFocus( ) , FormatDevErrorMsg( wDevError , wNumErrors ) , (LPSTR)szAppName , MB_OK | MB_ICONHAND );
}
SelectObject( hDC , hOldFont );
ReleaseDC( hWnd , hDC );
/* Say that we displayed at least one set of registers. */
bDisplayed = TRUE;
}/* GetNewData( ) */
PRIVATE LPSTR NEAR PASCAL FormatDevErrorMsg( wDevError , wNumErrors )
WORD wDevError;
WORD wNumErrors;
{
BOOL bMemory;
register WORD wIndex;
WORD wErrors;
wIndex = wErrors = 0;
*szString = '\0';
bMemory = FALSE;
/* Build an error message. */
if( wDevError )
{
do
{
if( !wIndex )
{
wIndex = 1;
}
else
{
wIndex <<= 1;
}
switch( wIndex & wDevError )
{
case DEVERROR_OVERRUN:
if( wErrors )
{
strcat( szString , "; " );
}
strcat( szString , "Buffer overrun error" );
wErrors++;
break;
case DEVERROR_INTERNAL:
if( wErrors )
{
strcat( szString , "; " );
}
strcat( szString , "Internal error" );
wErrors++;
break;
case DEVERROR_NOTOWNER:
if( wErrors )
{
strcat( szString , "; " );
}
strcat( szString , "Device not owned by this window error" );
wErrors++;
break;
}
}
while( wIndex != HIGHEST_DEVERROR );
sprintf( szString + strlen( szString ) , " (%u errors in all)." , wNumErrors );
}
else
{
strcpy( szString , "No errors." );
}
return (LPSTR)szString;
}/* FormatDevErrorMsg( ) */
/* EOF */